package com.sghd.football.module.game.service.core;

import com.sghd.common.utils.math.MathUtils;
import com.sghd.football.module.game.service.config.model.ConfigRoom;
import com.sghd.football.module.game.service.model.IPlayer;
import com.sghd.football.module.game.service.model.PropType;
import com.sghd.football.module.game.service.model.Result;
import org.apache.commons.collections.MapUtils;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

/**
 * \* Created with 王创辉.
 * \* Date: 2018/5/21
 * \* Time: 16:14
 * \* @desc:
 */
public class Player extends IPlayer {

    /** 玩家棋盘*/
    protected ChessBoard chessBoard;
    /** 玩家所在游戏编号*/
    protected int gameId = -1;
    /** 玩家所在房间编号*/
    protected int roomId = -1;
    /** 玩家所在桌子编号*/
    protected int deskId = -1;
    /** 玩家所在座位编号*/
    protected int seat = -1;
    /** 最后操作时间*/
    protected Date lastUpdate;
    protected int freeCount = 0;
    /** 免费旋转中累计获得的金币*/
    protected int freeMoney = 0;
    private boolean reconn = false;
    /** 3分钟超时控制变量*/
    private boolean tmt = false;
    /** 退出标记*/
    private boolean exit = false;

    public static Player valueOf(long playerId, String nickName, String headUrl, int playerSex, String presentation, int vipLevel) {
        Player player = new Player();
        player.playerId = playerId;
        player.nickName = nickName;
        player.headUrl = headUrl;
        player.playerSex = playerSex;
        player.presentation = presentation;
        player.vipLevel = vipLevel;
        player.lastUpdate = new Date();
        return player;
    }

    public void enter(int seat, int deskId, ChessBoard chessBoard) {
        this.seat = seat;
        this.deskId = deskId;
        this.chessBoard = chessBoard;
        this.lastUpdate = new Date();
    }

    public void change(PropType type, long change) {
        long value = MapUtils.getLong(bagInfo, type);
        value += change;
//        if (value < 0) {
//            value = 0;
//        }
        bagInfo.put(type, value);
    }

    public Player update(Player player) {
        this.bagInfo = player.bagInfo;//更新背包
        return this;
    }

    public void decressFree() {
        freeCount--;
    }

    /**
     * 旋转
     *
     * @param roomId
     * @param free
     * @return
     */
    public Result operator(boolean free, Room room, int baseBet, int betIndex, long totalBet, ConfigRoom config) {
//        this.lastUpdate = new Date();
//        ConfigRoom configRoom = room.getConfigRoom();
//        Result result = chessBoard.operator(roomId, free, baseBet);
//        if (room.getRefundPool(betIndex) < configRoom.getNormalRandomSection()) {
//            if (result.getTotalFen() == 0) {
//                return result;
//            }
//            if (RandomUtils.isHit(configRoom.getNormalPeiRate())) {
//                int bei = (int) (result.getTotalFen() / (baseBet * Rule.size()));
//                if (bei <= configRoom.getNormalBei()) {
//                    return result;
//                } else {
//                    return operator(free, room, baseBet, betIndex);
//                }
//            }
//        }
//        return result;
        AtomicLong pool = room.getRefund(betIndex);
        Result result = chessBoard.operator(roomId, free, baseBet);
        this.lastUpdate = new Date();
        synchronized (pool) {
            if (pool.get() < config.getRefundCtrl().get(betIndex)[0] * baseBet * Rule.size()) {
                while (true) {
                    if (result.getTotalFen() <= baseBet * Rule.size()) {//当前是免费旋转
                        break;
                    }
                    result = chessBoard.operator(roomId, free, baseBet);
                }
            } else if (pool.get() >= config.getRefundCtrl().get(betIndex)[1] * baseBet * Rule.size()) {//反分池大于0
                while (true) {
                    if (result.getTotalFen() > 0) {
                        break;
                    }
                    result = chessBoard.operator(roomId, free, baseBet);
                }
            }
            long fan = (long) (totalBet * config.getRefund());//抽入反分池
            pool.set(MathUtils.overstep(pool.get(), fan - result.getTotalFen()));
            return result;
        }
    }

    public void setSeat(int seat) {
        this.seat = seat;
    }

    public int getRoomId() {
        return roomId;
    }

    public int getDeskId() {
        return deskId;
    }

    public int getSeat() {
        return seat;
    }

    public ChessBoard getChessBoard() {
        return chessBoard;
    }

    public void setChessBoard(ChessBoard chessBoard) {
        this.chessBoard = chessBoard;
    }

    public int getGameId() {
        return gameId;
    }

    public void setGameId(int gameId) {
        this.gameId = gameId;
    }

    public void setRoomId(int roomId) {
        this.roomId = roomId;
    }

    public void setDeskId(int deskId) {
        this.deskId = deskId;
    }

    public int getFreeCount() {
        return freeCount;
    }

    public void setFreeCount(int freeCount) {
        this.freeCount = freeCount;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Player player = (Player) o;
        return playerId == player.playerId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(playerId);
    }

    public void addFreeMoney(long totalFen) {
        this.freeMoney += totalFen;
    }

    public void setFreeMoney(int freeMoney) {
        this.freeMoney = freeMoney;
    }

    public int getFreeMoney() {
        return freeMoney;
    }

    public boolean isReconn() {
        return reconn;
    }

    public void setReconn(boolean reconn) {
        this.reconn = reconn;
    }

    public boolean isTmt() {
        return tmt;
    }

    public void setTmt(boolean tmt) {
        this.tmt = tmt;
    }

    public boolean isExit() {
        return exit;
    }

    public void setExit(boolean exit) {
        this.exit = exit;
    }
}
